package org.javaforever.cookieshop.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.javaforever.cookieshop.domain.PermissionBean;
import org.javaforever.cookieshop.domain.RoleBean;
import org.javaforever.cookieshop.domain.UserBean;
import org.javaforever.cookieshop.service.RoleService;
import org.javaforever.cookieshop.service.UserService;
import org.javaforever.cookieshop.shiro.UserRegisteAndLogin;
import org.javaforever.cookieshop.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

@RequestMapping(value = "/loginController")
@RestController
public class LoginController {
	public UserBean tempUser = new UserBean();
	@Autowired
	protected RoleService roleService;
	@Autowired
	protected UserService service;
	protected HttpSession session;

	@RequestMapping(value = "/addUploadUserPhoto", method = RequestMethod.POST)
	@ResponseBody
	public Map<String,Object> addUploadUserPhoto(MultipartHttpServletRequest request) throws Exception{
        Map<String, Object> result = new TreeMap<String, Object>();
        Iterator iter = request.getFileNames();
        byte[] imageBytes = null;

        while (iter.hasNext()) {
            MultipartFile file = request.getFile(iter.next().toString());

            if (file != null) {
                imageBytes = file.getBytes();
                if (tempUser == null) tempUser = new UserBean();
                tempUser.setPhoto(imageBytes);
                break;
            }
        }
        if (imageBytes != null) {
            result.put("success", true);
            result.put("data", imageBytes);
        } else {
            result.put("success", false);
            result.put("data", null);
        }
        return result;
	}
	@RequestMapping(value = "/loginUser", method = RequestMethod.POST)
	public Map<String,Object> loginUser(@RequestBody UserBean user) throws Exception{
        Map<String,Object> result = new TreeMap<String,Object>();
        String salt = service.getSaltUser(user.getUserName());
        user.setPassword(UserRegisteAndLogin.getInputPasswordCiph(user.getPassword(),salt));
        Subject subject = SecurityUtils.getSubject();
        String loginSuccess = UserRegisteAndLogin.userLogin(user);
        user = service.findUserByUserName(user.getUserName());
        if(user!=null&&!StringUtil.isBlank(user.getUserName())) {
            user = service.findUserByUserName(user.getUserName());        
            Set<String> roleNames=new HashSet<String>();
            Set<RoleBean> roles = service.listActiveUserRolesUsingUserId(user.getId());
            for(RoleBean role:roles){
                roleNames.add(role.getRoleName());
            }
            if (roleNames.contains("admin")) {
            	user.setIsadmin(true);
            }else {
            	user.setIsadmin(false);
            }
        }            
        subject.getSession().setAttribute("user", user);
        result.put("success",loginSuccess.equals("index"));
        result.put("token",subject.getSession().getId());
        result.put("data",null);
        return result;
	}
	@RequestMapping(value = "/logoutUser", method = RequestMethod.GET)
	public Map<String,Object> logoutUser() throws Exception{
        Map<String,Object> result = new TreeMap<String,Object>();
        try {
            UserBean user = (UserBean)SecurityUtils.getSubject().getPrincipal();
            SecurityUtils.getSubject().logout();
            
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        result.put("success",true);
        result.put("data",null);
        return result;
	}
	@RequestMapping(value = "/readMySession", method = RequestMethod.GET)
	public Map<String,Object> readMySession(HttpSession httpSession) throws Exception{
        Map<String,Object> result = new TreeMap<String,Object>();
        Session session  = SecurityUtils.getSubject().getSession();
        UserBean user = (UserBean)session.getAttribute("user");
        if(user!=null&&!StringUtil.isBlank(user.getUserName())) {
            user = service.findUserByUserName(user.getUserName());

        
            Set<String> roleNames=new HashSet<String>();
            List<String> privilegeNameList=new ArrayList<String>();
            
            Set<RoleBean> roles = service.listActiveUserRolesUsingUserId(user.getId());
            for(RoleBean role:roles){
                roleNames.add(role.getRoleName());
                Set<PermissionBean> privileges = roleService.listActiveRolePermissionsUsingRoleId(role.getId());
                for (PermissionBean privilege: privileges) {
                    privilegeNameList.add(privilege.getPermName());
                }
            }
    
            if(roleNames==null || roleNames.isEmpty())
            {
                roleNames.add("noAnyAuth");
            }
        
            if (roleNames.contains("admin")) {
            	user.setIsadmin(true);
            }else {
            	user.setIsadmin(false);
            }
            result.put("success",true);
            result.put("user",user);
            result.put("roles", roleNames);
            result.put("perms", privilegeNameList);
            return result;
        }else {
            result.put("success",false);
            result.put("user",null);
            result.put("roles", null);
            result.put("perms", null);
            return result;
        }
	}
	@RequestMapping(value = "/registerUser", method = RequestMethod.POST)
	public Map<String,Object> registerUser(@RequestBody UserBean user) throws Exception{
        Map<String,Object> result = new TreeMap<String,Object>();
        String userName = user.getUserName();
        String password = user.getPassword();
        int userCount = service.countUserByUserName(userName);
        if (userCount==0) {
            String[] saltAndCiphertext = UserRegisteAndLogin.encryptPassword(password);

            user.setSalt(saltAndCiphertext[0]);
            user.setPassword(saltAndCiphertext[1]);
            user.setLoginFailure(0);

            if (tempUser!=null && tempUser.getPhoto()!=null) {
                user.setPhoto(tempUser.getPhoto());
            }
            tempUser = new  UserBean();
            service.registerUser(user);
            user = service.findUserByUserName(user.getUserName());
            RoleBean role = roleService.findRoleByRoleName("user");
            service.assignRolesToUser(user.getId(), ""+role.getId());

            result.put("success",true);
            result.put("data",null);
            return result;
        }else {
            result.put("success",false);
            result.put("data",null);
            return result;
        }
	}
	@RequestMapping(value = "/updateUploadUserPhoto", method = RequestMethod.POST)
	@ResponseBody
	public Map<String,Object> updateUploadUserPhoto(MultipartHttpServletRequest request) throws Exception{
        Map<String, Object> result = new TreeMap<String, Object>();
        Iterator iter = request.getFileNames();
        byte[] imageBytes = null;

        while (iter.hasNext()) {
            MultipartFile file = request.getFile(iter.next().toString());

            if (file != null) {
                imageBytes = file.getBytes();
                if (tempUser == null) tempUser = new UserBean();
                tempUser.setPhoto(imageBytes);
                break;
            }
        }
        if (imageBytes != null) {
            result.put("success", true);
            result.put("data", imageBytes);
        } else {
            result.put("success", false);
            result.put("data", null);
        }
        return result;
	}
}

